package com.hmjk.health.background.data;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.json.JSONException;
import org.json.JSONObject;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.text.format.Time;
import android.util.Log;

import com.hmjk.health.HealthApp;
import com.hmjk.health.background.DataManager;
import com.hmjk.health.background.NetService;

public class UserFaceUpdated extends DataUpdated{
	private static String TAG = UserFaceUpdated.class.getSimpleName();
	private String faceFileName = null;
	private boolean downloading = false;
	private boolean committing = false;
	private Bitmap mBitmap = null;
	//private boolean reload = false;
	
	private void logd(String info){
		Log.d(TAG, info);
	}
	
	public UserFaceUpdated(HealthApp app, DataManager dm) {
		super(app, dm);
		UPDATE_TIME = 2 * 60 * 60 * 1000;
	}
	
	@Override
	public void setUserData(Object data) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public long delay() {				
		long curMs = System.currentTimeMillis();
		long del = curMs - upTime;
		logd("delay curMs="+curMs+" upTime="+upTime+" del="+del);
		if(del >= UPDATE_TIME){
			logd("delay 0");
			return 0;
		}else{
			logd("delay (UPDATE_TIME - del) = "+(UPDATE_TIME - del));
			return (UPDATE_TIME - del);
		}
	}
	
	private void download(){
		String uid = mApp.getUID();
		logd("download uid="+uid);
		if(uid == null)
			return;
		downloading = true;
		
		String downfilePath = mApp.getDownloadFaceFolder();
		downfilePath += "/" + uid + ".jpg";
		Intent si = new Intent(NetService.DOWNLOAD_ACTION);
		si.putExtra("sub_act", NetService.DOWNLOAD_USER_FACE);
		si.putExtra("uid", uid);
		si.putExtra("type", "m");
		si.putExtra("path", downfilePath);
		
		Time t = new Time();
		t.setToNow();
		String stamp = "DOWNLOAD_USER_FACE_MINE" + t.toString(); 
		si.putExtra("stamp",stamp);
		mApp.addNetHandler(stamp,mDm.getBackGroundHandler());
		mApp.startService(si);
	}

	private void doRequest(String uid){
		if(faceFileName == null){
			faceFileName = mApp.getFaceFileName(uid);
		}
		
		long lstamp = 0;
		if(faceFileName != null){
			int pos = faceFileName.lastIndexOf(File.separator);
			String name = faceFileName.substring(pos+1);
			int len = uid.length();
			
			String sstamp = name.substring(len);
			pos = sstamp.lastIndexOf(".");
			if(pos > 0){
				sstamp = sstamp.substring(0, pos);
			}
			lstamp = Long.parseLong(sstamp);
		}
		Intent si = new Intent(NetService.GET_DATA_ACTION);
		si.putExtra("sub_act", NetService.CHECK_USER_FACE);
		si.putExtra("uid", uid);
		si.putExtra("vuid", uid);
		//if(vstamp.trim().isEmpty())
		//	vstamp = "null";
		si.putExtra("vstamp", lstamp);
			
		Time t = new Time();
		t.setToNow();
		String stamp = "CHECK_USER_FACE_MINE" + t.toString(); 
		si.putExtra("stamp",stamp);
		mApp.addNetHandler(stamp,mDm.getBackGroundHandler());
		mApp.startService(si);
	}
	
	@Override
	public boolean grab() {
		String uid = mApp.getUID();
		logd("grab uid="+uid);
		if(uid == null)
			return false;
		
		if(downloading){
			logd("grab downloading");
			return false;
		}
		
		if(committing){
			logd("grab committing");
			return false;
		}
		
		long curMs = System.currentTimeMillis();
		logd("grab curMs="+curMs+" reqTime="+reqTime);
		if((curMs - reqTime) > UPDATE_TIME){
			doRequest(uid);
			reqTime = curMs;
			logd("grab req sent!");
			return true;
		}
		return false;
	}

	@Override
	public boolean grabByUser() {
		String uid = mApp.getUID();
		logd("grabByUser uid="+uid);
		if(uid == null)
			return false;
		
		if(downloading){
			logd("grabByUser downloading");
			return false;
		}
		
		if(committing){
			logd("grab committing");
			return false;
		}
		
		long curMs = System.currentTimeMillis();
		logd("grabByUser curMs="+curMs+" reqTime="+reqTime);
		if((curMs - reqTime) > 30 * 1000){
			doRequest(uid);
			reqTime = curMs;
			logd("grabByUser req sent!");
			return true;
		}
		return false;
	}

	@Override
	public void receive(String stamp, String sjson) {
		if(stamp.startsWith("CHECK_USER_FACE_MINE")){
		if(sjson != null){
			boolean update = false;
			try {
				JSONObject json = new JSONObject(sjson);
				int code = json.getInt("code");
				if(code == 200){
					String state = json.getString("state");
					if(state.equalsIgnoreCase("00")){
						update = false;
						upTime = System.currentTimeMillis();
					}else if(state.equalsIgnoreCase("22")){
						update = true;
					}else{
						Log.e(TAG, "receive error state:"+state+" from network");
					}
				}
			}catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
			
			if(update == false){
				Intent i = new Intent(DataManager.DATA_UPDATE_ACTION);
				i.putExtra("type",DataManager.F_USERFACE);
				i.putExtra("state", update);
				mApp.sendBroadcast(i);
			}else{
				download();
			}
		}
		}else if(stamp.startsWith("DOWNLOAD_USER_FACE_MINE")){
			if(sjson != null){
				boolean update = false;
				try {
					JSONObject json = new JSONObject(sjson);
					int code = json.getInt("code");
					if(code == 200){
						String state = json.getString("state");
						if(state.equalsIgnoreCase("00")){
							clearCurrent();
							JSONObject sd = json.getJSONObject("senddata");
							JSONObject recdata = json.getJSONObject("recdata");
							if(sd != null){
								String uid = sd.getString("uid");
								if(recdata != null){
									long time = recdata.getLong("timestamp");
									String filepath = json.getString("downloadfile");
									File f = new File(filepath);
									String facePath = mApp.getFaceFolder() + "/" + uid + time + ".jpg";
									File faceFile = new File(facePath);
									f.renameTo(faceFile);
								}
							}
							
							update = true;
							upTime = System.currentTimeMillis();
							//reload = true;
						}
					}else{
						upTime = System.currentTimeMillis();
						update = false;
					}
				}catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} 
				downloading = false;
				Intent i = new Intent(DataManager.DATA_UPDATE_ACTION);
				i.putExtra("type",DataManager.F_USERFACE);
				i.putExtra("state", update);
				mApp.sendBroadcast(i);
			}
		}else if(stamp.startsWith("COMMIT_USER_FACE")){
			if(sjson != null){
				int code = 404;
				String state = "af";
				try {
					JSONObject json = new JSONObject(sjson);
					code = json.getInt("code");
					if(code == 200){
						state = json.getString("state");
						if(state.equalsIgnoreCase("00")){
							clearCurrent();
							JSONObject sd = json.getJSONObject("senddata");
							JSONObject recdata = json.getJSONObject("recdata");
							if(sd != null){
								String uid = sd.getString("uid");
								if(recdata != null){
									long time = recdata.getLong("facetimestamp");
									String filepath = json.getString("uploadfile");
									File f = new File(filepath);
									String facePath = mApp.getFaceFolder() + "/" + uid + time + ".jpg";
									File faceFile = new File(facePath);
									f.renameTo(faceFile);
								}
							}
						}
					}
				}catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} 
				committing = false;
				Intent i = new Intent(DataManager.DATA_COMMIT_RESULT);
				i.putExtra("type",DataManager.F_USERFACE);
				i.putExtra("state", state);
				i.putExtra("code", code);
				mApp.sendBroadcast(i);
			}
		}
	}

	private void clearCurrent(){
		if(faceFileName == null){
			faceFileName = mApp.getFaceFileName(mApp.getUID());
		}
		
		if(mBitmap != null){
			if(!mBitmap.isRecycled()){
				mBitmap.recycle();
				System.gc();
			}
		}
		mBitmap = null;
		
		if(faceFileName != null){
			File f = new File(faceFileName);
			if(f.exists())
				f.delete();
		}
		
		faceFileName = null;
	}
	
	@Override
	public Bitmap check(String[] arg) {
		String uid = mApp.getUID();
		logd("check uid="+uid);
		if(uid == null)
			return null;
		
		if(faceFileName == null){
			faceFileName = mApp.getFaceFileName(uid);
		}
		
		if(faceFileName == null){
			if(mBitmap != null){
				if(!mBitmap.isRecycled()){
					mBitmap.recycle();
					System.gc();
				}
			}
			mBitmap = null;
		}else{
			if(mBitmap == null){
				loadBitmap();
			}
		}
		return mBitmap;
	}
	
	private void loadBitmap(){
		if(faceFileName != null){
			InputStream bmpIs = null;
			try{
				Uri imageUri = Uri.parse("file://" + faceFileName);
				bmpIs = mApp.getContentResolver().openInputStream(imageUri);
				if(mBitmap != null){
					if(!mBitmap.isRecycled()){
						mBitmap.recycle();
						System.gc();
					}
				}
				mBitmap = BitmapFactory.decodeStream(bmpIs);
				bmpIs.close();
			}catch(FileNotFoundException e){
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	@Override
	public boolean commit(Object data) {
		String path = (String) data;
		
		String uid = mApp.getUID();
		
		if((uid == null) || uid.isEmpty())
			return false;
		
		if((path == null) || (path.trim().length() == 0))
			return false;
		
		File f = new File(path);
		if(f.exists()){
			Intent si = new Intent(NetService.COMMIT_DATA_ACTION);
			si.putExtra("sub_act", NetService.COMMIT_USER_FACE);
			si.putExtra("uid", uid);
			si.putExtra("path", path);
			Time t = new Time();
			t.setToNow();
			String stamp = "COMMIT_USER_FACE" + t.toString(); 
			si.putExtra("stamp",stamp);
			mApp.addNetHandler(stamp,mDm.getBackGroundHandler());
			mApp.startService(si);
			committing = true;
			return true;
		}
		return false;
		
	}
	
	@Override
	public void release() {
		if(mBitmap != null){
			if(!mBitmap.isRecycled()){
				mBitmap.recycle();
				System.gc();
			}
		}
		mBitmap = null;
		faceFileName = null;
	}

}
